package com.dongdong.filter;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.dongdong.result.Result;
import com.dongdong.result.ResultConstant;
import com.dongdong.result.ResultEnums;
import com.dongdong.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Set;

@Order(-1) //**order值越小，优先级越高，执行顺序越靠前**     当过滤器的order值一样时，会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行
@Component  //放到ioc容器中
public class LoginGlobelFilter implements GlobalFilter {

    @Autowired
    private JwtUtil jwtUtil;

    //获取ymL文件中需要排除的路径    将字符串截取后取出集合
    @Value("#{'${exclude.url}'.empty?null:'${exclude.url}'.split(',')}")
    private Set<String> urls;

    //创建匹配类
    private AntPathMatcher matcher = new AntPathMatcher();

    /**
     * 处理当前请求，有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文，里面可以获取Request、Response等信息
     * @param chain    用来把请求委托给下一个过滤器
     * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取请求
         ServerHttpRequest request = exchange.getRequest();

        //获取前端请求路径
        String path = request.getURI().getPath();//LoginController/login
        // 判断这个路径是否跟set集合中的路径匹配
        for (String url : urls) {//index/**,//LoginController/**
            if (matcher.match(url,path)) {
                //true :匹配 放行
                return chain.filter(exchange);
            }
           }
         //获取请求头
         HttpHeaders headers = request.getHeaders();
         //获取前端传递过来的token
         String token = headers.getFirst(  "token");
       // 判断是否为null
        if(token==null || "".equals(token)){
            return getVoidMono(exchange);//放行
        }
        //解析token
        try {
            jwtUtil.parseJwt(token);
                                    /*            //         解析token
                                                Claims claims = jwtUtil.parseJwt(token);
                                                String id = claims.getId();
                                                System.out.println("id------>>"+id);
                                                String userStr = claims.getSubject();
                                    //         转换成对象  脱敏处理
                                    //         TUser user1 = JSONObject.parseObject(userStr, TUser.class);
                                                TUserVO user1 = JSONObject.parseObject(userStr, TUserVO.class);
                                                System.out.println(user1);*/
        } catch (Exception e) {
            //获取响应
            return getVoidMono(exchange);
        }
        return chain.filter(exchange);//放行
    }
    private static Mono<Void> getVoidMono(ServerWebExchange exchange) {
        //获取响应
        ServerHttpResponse response = exchange.getResponse();
        //设置状态码
        response.setStatusCode (HttpStatus.OK);//401：UNAUTHORIZED   200：OK
        //设置响应编码    防止乱码
        response.getHeaders().add("Content-Type", "application/json;charset=utf-8");

        //设置给前端的返回值信息
//        Result<Object> result = new Result<>(ResultConstant.TOKEN_FAIL_CODE, ResultConstant.TOKEN_FAIL_MSG);
        Result result =  Result.RESPONSE(ResultEnums.TOKEN_FAIL);
        //把result返回值转换为byte[]   // SerializerFeature. WriteMapNulLValue:不转换为mull的数据
        byte[] bytes = JSONObject.toJSONBytes(result, SerializerFeature.WriteMapNullValue);
        DataBuffer wrap = response.bufferFactory().wrap(bytes);

        return response.writeWith(Mono.just(wrap));
    }


}
